package com.leps.nq.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leps.nq.common.util.SecurityUtil;
import com.leps.nq.sys.entity.SysMenu;
import com.leps.nq.sys.entity.SysRole;
import com.leps.nq.sys.entity.SysRoleMenu;
import com.leps.nq.sys.mapper.SysMenuMapper;
import com.leps.nq.sys.mapper.SysRoleMapper;
import com.leps.nq.sys.mapper.SysRoleMenuMapper;
import com.leps.nq.sys.service.ISysRoleService;
import com.leps.nq.sys.vo.CreateRoleVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色信息表 服务实现类
 * </p>
 *
 * @author hex
 * @since 2022-05-20
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {

    @Autowired
    private SysMenuMapper menuMapper;

    @Autowired
    private SysRoleMenuMapper roleMenuMapper;

    @Override
    public List<SysRole> selectRoles() {
        return this.getBaseMapper().selectRoleAll();
    }

    @Override
    public SysRole selectById(Long roleId) {
        return this.getBaseMapper().selectRoleById(roleId);
    }

    @Override
    public List<SysMenu> selectMenusByRoleId(Long roleId) {
        return this.menuMapper.selectMenuListByRoleId(roleId);
    }

    @Override
    @Transactional
    public boolean createRole(CreateRoleVo createRoleVo) {
        int rows = 0;
        // type convert
        SysRole sysRole = BeanUtil.toBean(createRoleVo, SysRole.class);
        // fill default status: enabled
        sysRole.setStatus("0");
        sysRole.setCreateBy(SecurityUtil.getUserName());
        // save role
        rows += this.getBaseMapper().insertRole(sysRole);
        // check menuIds
        Long[] menuIds = createRoleVo.getMenuIds();
        if (menuIds == null || menuIds.length == 0) return rows > 0;
        // if menuIds provided, insert into sys_role_menu
        ArrayList<SysRoleMenu> sysRoleMenus = new ArrayList<>();
        final Long roleId = sysRole.getRoleId();
        for (Long menuId : menuIds) {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setRoleId(roleId);
            sysRoleMenu.setMenuId(menuId);
            sysRoleMenus.add(sysRoleMenu);
        }
        rows += this.roleMenuMapper.batchRoleMenu(sysRoleMenus);
        return rows == (1 + menuIds.length);
    }

    @Override
    @Transactional
    public boolean grantMenusToRole(Long roleId, Long[] menuIds) {
        // clear role_menu of this role
        this.roleMenuMapper.deleteRoleMenuByRoleId(roleId);
        // re insert role_menu
        List<SysRoleMenu> roleMenus = Arrays.stream(menuIds).map(menuId -> {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setRoleId(roleId);
            sysRoleMenu.setMenuId(menuId);
            return sysRoleMenu;
        }).collect(Collectors.toList());
        int row = this.roleMenuMapper.batchRoleMenu(roleMenus);
        return row > 0;
    }

    @Override
    public boolean updateRole(SysRole sysRole) {
        String updateBy = SecurityUtil.getUserName();
        sysRole.setUpdateBy(updateBy);
        return this.getBaseMapper().updateRole(sysRole) > 0;
    }

    @Override
    public boolean changeStatus(Long roleId, String status) {
        SysRole sysRole = new SysRole();
        sysRole.setRoleId(roleId);
        sysRole.setStatus(status);
        sysRole.setUpdateBy(SecurityUtil.getUserName());
        return this.getBaseMapper().updateRole(sysRole) > 0;
    }

    @Override
    public boolean removeRole(Long[] roleIds) {
        int rows = this.getBaseMapper().deleteRoleByIds(roleIds);
        return rows > 0;
    }
}
